以太坊
以太坊的概念
以太坊(英文Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(Ethereum Virtual Machine)来处理点对点合约。
以太坊的概念首次在2013至2014年间由程序员Vitalik Buterin受比特币启发后提出,大意为“下一代加密货币与去中心化应用平台”,在2014年通过ICO众筹开始得以发展。
官方简介
以太坊是一个全球性的、去中心化的金融和新型应用程序平台。在以太坊,我们可以通过代码来控制资产,并建立世界上任何地方皆可访问的应用程序。
更多介绍请参考以太坊白皮书以及官网。
以太坊的特点
智能合约
世界计算机
以太坊关键概念
(1)账户 作为内置了加密货币的系统,以太坊同比特币的单一UTXO模型不一样,具有账户(Account)的概念。以太坊的账户分为外部账户(Externally Owned Accounts,EOA)和合约账户(Contract Accounts)。账户为密码学意义上的账户,跟比特币一样控制了私钥就控制了账户的操作权。 1)外部账户为一般意义上的用户账户,用户在创建账户时自动生成公私钥对,编码存放在Keyfile中,私钥使用用户口令加密,公钥哈希值截取后20位作为账户地址。 2)合约账户保存在以太坊区块链上,是合约代码(功能)和数据(状态)的集合。合约账户通过外部账户或既存合约账户进行部署和操作控制。在部署合约二进制代码时由以太坊虚拟机(EVM)基于创建者账户地址、创建者交易nonce生成账户地址。账户地址生成过程如 (2)交易 以太坊的交易(Transaction)是外部账户发往其他账户(外部账户或合约账户)报文结构体,主要包括接受者地址(0地址代表新建合约实例)、发送者签名、发送金额、数据域(若接收方为合约账户)、Gas上限和Gas价格。 (3)消息 以太坊的消息(Message)是合约账户发往其他账户(外部账户或合约账户)报文结构体,主要包括消息发送者、消息接受者地址、发送金额、数据域(若接收方为合约账户)和Gas上限。合约可以通过消息调用的方式来调用其他合约,或者发送以太币到非合约账户。消息调用和交易非常类似,它们都有一个源,一个目标,数据负载,以太币,Gas和返回数据。事实上每个交易都可以被认为是一个顶层消息调用,这个消息调用会依次产生更多的消息调用。
(4)Gas 由于以太坊为公有链设计,为了避免恶意程序无代价发动DoS攻击或滥用以太坊网络,参考比特币引入了经济概念,所有在以太坊EVM上的操作和存储消耗都需要Gas。交易发送者设定Gas上限和Gas价格作为矿工打包费用。如果费用过低,矿工可以选择不打包交易到区块。 合约在执行过程中,如果当前代码执行以及子消息产生的代码执行发生的所有Gas消耗超过Gas上限,矿工依然可以获得打包费用,但是当前交易的所有状态都会被回滚。如果未出现Gas耗尽(gas overrun),交易成功执行,所有未消耗的Ether(以太币)依然会返回发送者账户。 矿工挖矿获得Ether,合约执行消耗Ether,形成天然的供求关系。Gas只与程序逻辑处理复杂度有关,将其与市场波动相关的Ether价格隔离开,通过发送者设定Gas Price(燃料价格),以太坊设计了一套对抗通货紧缩/膨胀的方法。 (5)合约 以太坊的合约(Contract)即为合约账户,是以EVM字节码形式存储的代码(功能)和数据(状态)的集合体。它们以Patricia树组织,存储在区块链的账户地址上,账户可以相互发送交易(Transaction)或消息事件(Message Event),在Gas上限内进行一次交易的图灵完备运算。交易发送者支付“实际消耗Gas*指定GasPrice”的Ether给矿工作为费用,将此交易和结果打包到下一个区块上为智能合约间的交互示意图。 智能合约间的交互 (6)以太坊虚拟机 以太坊虚拟机(EVM)是智能合约的运行环境,是比JVM或Docker VM“沙箱”模式还严格的一种完全隔离的虚拟机运行环境。运行在EVM中的合约代码无法访问网络、文件系统和其他进程,合约之间的访问也受到严格限制。EVM是基于栈操作的虚拟机,栈最大深度1024,每个元素32字节,其指令集由最基本的算术、位、逻辑、比较、条件跳转、无条件跳转这些满足图灵完备的最小指令集组成,EVM可以发送消息调用其他合约,还可以加载目标地址的合约代码在当前合约上下文执行(callcode)。 (7)DApp DApp直接关联起用户和服务提供方,即买卖双方的应用。以太坊提供多种语言版本的API客户端,并通过以太坊客户端接入网络,DApp基于这些API客户端,把需要共识的业务逻辑和数据以合约的形式部署到以太坊区块链上,并按照需要执行API调用操作。那些不需要共识的逻辑在DApp自身中实现,以降低运行成本。
以太坊的每一个区块头中并非只包含一棵Merkle树,而是包含了3棵Merkle树,分别对应了以下3种对象: ·交易(Transactions) ·收据(Receipts,基本上,它是展示每一笔交易影响的数据条) ·状态(State) 这三棵树允许轻客户端轻松地进行并核实以下类型的查询答案: 1)这笔交易被包含在特定的区块中了吗? 2)告诉我这个地址在过去30天中,发出X类型事件的所有实例(例如,一个众筹合约完成了它的目标)。 3)目前我的账户余额是多少? 4)这个账户是否存在? 5)假装在这个合约中运行这笔交易,它的输出会是什么? 第一种是由交易树(transaction tree)来处理的;第3和第4种则是由状态树(state tree)负责处理,第2种则由收据树(receipt tree)处理。计算前4个查询任务是相当简单的。在服务器简单地找到对象,获取梅克尔分支,并通过分支来回复轻客户端。第5种查询任务同样也是由状态树处理。 7.RLP RLP(Recursive Length Prefix,递归长度前缀编码)是Ethereum中对象序列化的一个主要编码方式,其目的是对任意嵌套的二进制数据的序列进行编码。 以太坊中的所有数据都以“递归长度前缀编码”(Recursive Length Prefix encoding,RLP)形式存储,这种编码格式将任意长度和维度的字符串构成的数组串连接成字符串。例如,[’dog‘,’cat‘]被串接(以字节数组格式)为[130,67,100,111,103,67,99,97,116];其基本的思想是把数据类型和长度编码成一个单独的字节放在实际数据的前面(例如‘dog’的字节数组编码为[100,111,103],于是串接后就成了[67,100,111,103])。注意RLP编码正如其名字表示的一样,是递归的;当RLP编码一个数组时,实际上是在对每一个元素的RLP编码级联成的字符串编码。需要进一步提请注意的是,以太坊中所有数据都是整数;所以,如果有任何的以一个或多个0字节开头的哈希或者地址,这些0字节应该在计算出现问题的时候去除。以太坊中没有串接数据结构包含任何以0开头的数值。整数以大端基础(Big Endian)256格式存储(例如32767字节数组格式为[127,255])。
以太坊与比特币的对比
以太坊与比特币都是工作量证明POW机制(目前转化成权益机制),两者都是点对点网络,两者都基于密码学,数字签名与哈希函数来保证系统的不可篡改以及安全。两者都有数字货币运行。
比特币:电子货币,支付
以太坊:世界计算机,功能,合约
比特币:点对点支付
以太坊:虚拟机执行合约
比特币:记录交易
以太坊:记录交易,记录合约或程序
比特币:电子货币
以太坊:Ether 是功能型,用来支付GAS,使用费用。
以太坊的账户、交易与燃料费
以太坊是有账户的,每个用户都可以开设账户,账户余额是我们拥有的以太币,用户还可以用账户持有遵循ERC20标准、ERC721标准的通证。 我们开设的账户是以太坊的两种账户中的外部账户,而当程序员部署一个智能合约时则会创建合约账户: ·外部账户(externally owned accounts),由私钥控制。 ·合约账户(contract accounts),由智能合约的代码控制。
外部账户可以触发交易,用户用私钥签名,执行一个交易。合约账户不能主动发起交易,它只能在被触发后,按预先编写的代码执行,但它可以接着调用其他智能合约的代码。两种账户的地址形式是一致的,都是以“0x”为前缀的40位十六进制字符串,我们接下来把它们统称为“账户地址”或“以太坊地址”
要创建以太坊账户,只需要一个非对称加密密钥对——由不同的算法(例如RSA、ECC等)生成。以太坊使用椭圆曲线加密算法(ECC),ECC有多个参数用来调节速度和安全性,以太坊使用secp256k1参数。以太坊使用256位加密。以太坊私钥/公钥是一个256位数。因为处理器不能表示这么大的数,所以它被编译成长度为64的十六进制字符串。
每个账户用一个地址表示。有了密钥之后,就需要生成地址。从公钥生成地址的过程如下: 1)生成公钥的keccak-256哈希。它将给出一个256位的数字。 2)丢弃前面的96位,即12字节。现在得到160位二进制数据,即20字节。 3)把地址编译成十六进制的字符串。最后将得到一个40字符的字节串,就是账户地址。
交易
以太坊中有两大类交易:第一类是转账交易,将以太币从一个账户转到另一个账户,第二类是外部账户调用合约账户的函数,触发智能合约的代码运行。
两种交易都由同一种交易实现,用户发起的交易均是打包在一起的二进制数据,包括如下内容 ·nonce:与发起这个交易的外部账户相关的一个序列编号。 ·gas price:交易的发起方愿支付的燃料费价格。 ·gas limit:交易的发起方愿意为交易支付的最大的燃料数量。 ·recepient:交易的目标地址,可以是另一个外部账户,也可以是合约账户。 ·value:这一交易发送的以太币数量。 ·data:附在交易中的数据,当我们调用一个智能合约的函数时,调用数据被组合成相应的格式放入这个字段
如上以太坊的交易时,打包数据包含以下内容: ·地址、私钥:我们用它们控制一个账户。 ·通证:它是价值的表示物,指我们的账户所掌控的价值。 ·交易:我们可以向区块链发起执行一个转账交易。 ·智能合约:编写、部署在以太坊合约账户中的程序代码。 ·燃料费:发起一个交易时,我们要为这个交易所触发的所有操作支付燃料费。
燃料费
当我们调用智能合约中所有的会改变账本状态的所谓可写函数时,我们要支付燃料费。这使得以太坊这台所谓的世界计算机有点像一个按量计费的云服务提供商,在其上所进行的运算都要相应地支付费用。与云服务不同的是,这个费用不是由在应用的开发者支付,即不是由智能合约的开发者支付,而是由每一个调用智能合约的用户根据自己的使用量支付。在以太坊系统内,以太币的主要角色就是用于支付交易的燃料费。